
typedef struct list_node {
    struct list_node *prev;
    struct list_node *next;
} list_node;


static inline void list_insert_after(list_node *where, list_node *node)
{
    node->prev = where;
    node->next = where->next;
    where->next->prev = node;
    where->next = node;
}

static inline void list_insert_before(list_node *where, list_node *node)
{
    node->prev = where->prev;
    node->next = where;
    where->prev->next = node;
    where->prev = node;
}

static inline void list_merge_after(list_node *where, list_node *list)
{
    list_node *tail = list->prev;

    list->prev = where;
    tail->next = where->next;
    where->next->prev = tail;
    where->next = list;
}

static inline void list_merge_before(list_node *where, list_node *list)
{
    list_node *tail = list->prev;

    list->prev = where->prev;
    tail->next = where;
    where->prev->next = list;
    where->prev = tail;
}

static inline void list_delete(list_node *node)
{
    node->prev->next = node->next;
    node->next->prev = node->prev;
}

static inline list_node *list_remove_first(list_node *head)
{
    list_node *node = head->next;

    list_delete(node);
    
    return node;
}

static inline list_node *list_remove_last(list_node *head)
{
    list_node *node = head->prev;

    list_delete(node);
    
    return node;
}

static inline int list_is_empty(list_node *head)
{
    return head->prev == head;
}

static inline void list_init(list_node *node)
{
    node->prev = node;
    node->next = node;
}

#define list_container(ptr, type, member) \
        ((type *)((char *)(ptr)- offsetof(type, member)))

#define list_for_each(head, node) \
    for ((node)  = (head)->next; \
         (node) != (head); \
         (node)  = (node)->next)

#define list_for_each_safe(head, node, temp) \
    for ((node)  = (head)->next, (temp) = (node)->next; \
         (node) != (head); \
         (node)  = (temp), (temp)= (node)->next)

